//!
/**
 ***********************************************************************************************************
 * <RBD3D9VertexDeclaration Implementation>
 ***********************************************************************************************************
 * @file RBD3D9VertexDeclaration.cpp
 ***********************************************************************************************************/

/***********************************************************************************************************
 * Precompiled Header
 ***********************************************************************************************************/
#include "RBD3D9RendererPCH.h"

/***********************************************************************************************************
 * Includes
 ***********************************************************************************************************/
#include "RBD3D9VertexDeclaration.h"

#include "RBD3D9Renderer.h"

#include "RBMain/RBVertexElement.h"

/***********************************************************************************************************
 * Defines
 ***********************************************************************************************************/

/***********************************************************************************************************
 * Classes implementation
 ***********************************************************************************************************/

/**
 ***********************************************************************************************************
 * Constructor
 ***********************************************************************************************************/
RBD3D9VertexDeclaration::RBD3D9VertexDeclaration(RBHardwareBufferManager* pHBMgr, RBVertexElement* pElements, uint32 uiElementCount)
: RBVertexDeclaration(pHBMgr, pElements, uiElementCount)
{
    D3DVERTEXELEMENT9* pD3DElements = new D3DVERTEXELEMENT9[uiElementCount+1];
    uint32 aStreamOffset[RBVertexElement::MaxStreamCount] = {0};
    BYTE aStreamUsageIndex[RBVertexElement::MaxStreamCount][RBVertexElement::VEU_COUNT] = {0};
    for (uint32 uiElement=0; uiElement<uiElementCount; ++uiElement)
    {
        pD3DElements[uiElement].Stream     = pElements[uiElement].Stream;
        pD3DElements[uiElement].Offset     = (WORD)aStreamOffset[pElements[uiElement].Stream];
        pD3DElements[uiElement].Type       = (BYTE)pElements[uiElement].Type;
        pD3DElements[uiElement].Method     = D3DDECLMETHOD_DEFAULT;
        pD3DElements[uiElement].Usage      = (BYTE)pElements[uiElement].Usage;
        pD3DElements[uiElement].UsageIndex = aStreamUsageIndex[pElements[uiElement].Stream][pElements[uiElement].Usage]++;

        aStreamOffset[pElements[uiElement].Stream] += pElements[uiElement].GetSize();
    }

    D3DVERTEXELEMENT9 akEnd[] = D3DDECL_END();

    pD3DElements[uiElementCount].Stream = akEnd[0].Stream;
    pD3DElements[uiElementCount].Offset = akEnd[0].Offset;
    pD3DElements[uiElementCount].Type = akEnd[0].Type;
    pD3DElements[uiElementCount].Method = akEnd[0].Method;
    pD3DElements[uiElementCount].Usage = akEnd[0].Usage;
    pD3DElements[uiElementCount].UsageIndex = akEnd[0].UsageIndex;


    RBD3D9Renderer::GetSingleton()->GetD3DDevice()->CreateVertexDeclaration(pD3DElements, &m_pD3DDecl);

    RBDelete[] pD3DElements;
}

/**
 ***********************************************************************************************************
 * Destructor
 ***********************************************************************************************************/
RBD3D9VertexDeclaration::~RBD3D9VertexDeclaration()
{
    RBCommon::SafeRelease(m_pD3DDecl);
}

/***********************************************************************************************************/
